﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FormatTest
{
    /// <summary>
    /// 图像参数集语法
    /// </summary>
    public class pic_parameter_set_rbsp : base_func
    {

        public int pic_order_present_flag;
        public int redundant_pic_cnt_present_flag;
        public int weighted_pred_flag;
        public int weighted_bipred_idc;
        public int deblocking_filter_control_present_flag;
        public int num_slice_groups_minus1;
        public int slice_group_map_type;
        public int pic_size_in_map_units_minus1;
        public int slice_group_change_rate_minus1;
        public int entropy_coding_mode_flag;
        public int[] run_length_minus1;
        public int[] top_left;
        public int[] bottom_right;
        public int slice_group_change_direction_flag;

        public pic_parameter_set_rbsp(string bytes)
        {
            this.bytes = bytes;
            var pic_parameter_set_id = columbus_ue();
            var seq_parameter_set_id = columbus_ue();
            entropy_coding_mode_flag = read_one_bit();
            pic_order_present_flag = read_one_bit();
            num_slice_groups_minus1 = columbus_ue();
            if (num_slice_groups_minus1 > 0)
            {
                slice_group_map_type = columbus_ue();
                if (slice_group_map_type == 0)
                {
                    run_length_minus1 = new int[num_slice_groups_minus1 + 1];
                    for (var iGroup = 0; iGroup <= num_slice_groups_minus1; iGroup++)
                    {
                        run_length_minus1[iGroup] = columbus_ue();
                    }
                }
                else if (slice_group_map_type == 2)
                {
                    top_left = new int[num_slice_groups_minus1];
                    bottom_right = new int[num_slice_groups_minus1];
                    for (var iGroup = 0; iGroup < num_slice_groups_minus1; iGroup++)
                    {
                        top_left[iGroup] = columbus_ue();
                        bottom_right[iGroup] = columbus_ue();
                    }
                }
                else if (slice_group_map_type == 3 || slice_group_map_type == 4 || slice_group_map_type == 5)
                {
                    slice_group_change_direction_flag = read_one_bit();
                    slice_group_change_rate_minus1 = columbus_ue();
                }
                else if (slice_group_map_type == 6)
                {
                    pic_size_in_map_units_minus1 = columbus_ue();
                    var slice_group_id = new List<int>();
                    for (var i = 0; i <= pic_size_in_map_units_minus1; i++)
                    {
                        //list[i] = read_bits(number);
                        slice_group_id[i] = TwoToTen(read_bits(Convert.ToInt32(Math.Ceiling(Math.Log(num_slice_groups_minus1, 2)))));
                    }
                }
            }
            var num_ref_idx_l0_active_minus1 = columbus_ue();
            var num_ref_idx_l1_active_minus1 = columbus_ue();
            weighted_pred_flag = read_one_bit();
            weighted_bipred_idc = TwoToTen(read_bits(2));
            var pic_init_qp_minus26 = columbus_se();
            var pic_init_qs_minus26 = columbus_se();
            var chroma_qp_index_offset = columbus_se();
            deblocking_filter_control_present_flag = read_one_bit();
            var constrained_intra_pred_flag = read_bits(1);
            redundant_pic_cnt_present_flag = Convert.ToInt32(read_bits(1));
            if (more_rbsp_data())
            {
                var transform_8x8_mode_flag = Convert.ToInt32(read_bits(1));
                var pic_scaling_matrix_present_flag = Convert.ToInt32(read_bits(1));
                if (pic_scaling_matrix_present_flag != 0)
                {
                    var pic_scaling_list_present_flag = new List<int>();
                    for (var i = 0; i < 6 + 2 * transform_8x8_mode_flag; i++)
                    {
                        pic_scaling_list_present_flag[i] = Convert.ToInt32(read_bits(1));
                        if (pic_scaling_list_present_flag[i] != 0)
                        {
                            if (i < 6)
                            {
                                //???
                            }
                            else
                            {

                            }
                        }
                    }
                    var second_chroma_qp_index_offset = columbus_se();
                }
            }
            rbsp_trailing_bits();
        }

        private void scaling_list(List<int> scalingList, int sizeOfScalingList, bool useDefaultScalingMatrixFlag)
        {
            var lastScale = 8;
            var nextScale = 8;
            for (var j = 0; j < sizeOfScalingList; j++)
            {
                if (nextScale != 0)
                {
                    var delta_scale = columbus_se();
                    nextScale = (lastScale + delta_scale + 256) % 256;
                    useDefaultScalingMatrixFlag = (j == 0 && nextScale == 0);
                }
                scalingList[j] = (nextScale == 0) ? lastScale : nextScale;
                lastScale = scalingList[j];
            }
        }

        public int PicSizeInMapUnits
        {
            get
            {
                return this.pic_size_in_map_units_minus1 + 1;
            }
        }

        public int SliceGroupChangeRate
        {
            get
            {
                return this.slice_group_change_rate_minus1 + 1;
            }
        }
    }
}
